home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Arsenal Files 8
/
The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO
/
prg_casm
/
pcl4c60.zip
/
SELF32.C
< prev
next >
Wrap
Text File
|
1996-10-22
|
10KB
|
349 lines
/*
** --- selftest.c ---
**
** 32-bit DPMI version
**
** SELFTEST requires two serial ports on the same computer. The
** program transmits a test string on one port (FirstCOM) and
** receives on a second port (SecondCOM), where the two ports are
** connected via a null modem adapter. The received string is tested
** against the transmit string (they should be identical).
**
** Connect the two serial ports (on a single computer) together
** using a null modem cable. Be sure to modify the configuration
** section for non-standard PC ports or to setup your multiport
** board. Note that many multiport boards are either Digiboard or
** BOCA board compatible.
**
** IMPORTANT: You may have to modify the port address & IRQ to match
** your Digiboard or BOCA board installation.
**
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pcl4c32.h"
#include "sioerr32.h"
#define ESC 0x1b
#define CR 0x0d
#define LF 0x0a
#define ONE_SECOND 18
#define PC 1
#define DB 2
#define BB 3
/*** Global Variables ***/
#define TEST_SIZE 63
char LastRxChar = '\0';
char TestSet[TEST_SIZE];
int NbrRuns = 16;
int TestLength;
int FirstCOM;
int SecondCOM;
int MultiUART = 0;
int MultiIRQ = 0;
int MultiStatus = 0;
void AllDone(int);
void Display(int);
void CheckAlloc(int,char *);
int ErrorCheck(int);
int AllocSel(int);
int BaudMatch(char *);
void CheckOverrun(int);
void ShowStats(int);
static int RxSeg1 = 0;
static int TxSeg1 = 0;
static int RxSeg2 = 0;
static int TxSeg2 = 0;
/* standard PC port configuration */
static int StdAdrPC[4] = {0x3f8,0x2f8,0x3e8,0x2e8};
static int StdIrqPC[4] = {4,3,4,3};
static int BaudCode;
static char *BaudRate[10] = {"300","600","1200","2400","4800","9600",
"19200","38400","57600","115200"};
static int Selection = 0; /* PC, DB, or BB */
void main(int argc, char *argv[])
{int Port;
char *P;
int ComLimit = 0;
char c;
int Version;
int i, n, rc;
int RxQue;
int TxQue;
if(argc!=5)
{printf("Usage: self32 {pc|db|bb} 1stCom 2ndCom baudrate\n");
exit(1);
}
BaudCode = BaudMatch(argv[4]);
if(BaudCode==-1)
{printf("Bad baud rate '%s'\n",argv[4]);
exit(1);
}
P = argv[1];
if((strcmp(P,"pc")==0)||(strcmp(P,"PC")==0)) Selection = PC;
if((strcmp(P,"db")==0)||(strcmp(P,"DB")==0)) Selection = DB;
if((strcmp(P,"bb")==0)||(strcmp(P,"BB")==0)) Selection = BB;
if(Selection==0)
{puts("Must specify 'PC', 'DB' or 'BB' as 1st argument");
puts("EG: SELF32 PC 1 4 38400");
exit(1);
}
/* set port limit to 4 ports (shareware version) */
if(Selection==PC) ComLimit = COM4;
if(Selection==DB) ComLimit = COM4;
if(Selection==BB) ComLimit = COM4;
FirstCOM = atoi(argv[2]) -1;
SecondCOM = atoi(argv[3]) -1;
printf("FirstCOM = COM%d\n",1+FirstCOM);
printf("SecondCOM = COM%d\n",1+SecondCOM);
if(FirstCOM<COM1)
{puts("1stCom must be >= COM1");
exit(1);
}
if(SecondCOM>ComLimit)
{printf("2ndCom must be <= COM%d\n",1+ComLimit);
exit(1);
}
if(Selection==DB)
{/*** Custom Configuration: DigiBoard PC/8 ***/
MultiUART = 0x180; MultiIRQ = IRQ5; MultiStatus = 0x1C0;
printf("[ Configuring DigiBoard as COM1-COM%d (IRQ%d) @ 0x%x ]\n",
1+ComLimit,MultiIRQ,MultiUART);
ErrorCheck( SioPorts(1+ComLimit,COM1,MultiStatus,DIGIBOARD) );
for(Port=COM1;Port<=ComLimit;Port++)
{/* set DigiBoard UART addresses */
ErrorCheck( SioUART(Port,MultiUART+8*Port) );
/* set DigiBoard IRQ */
ErrorCheck( SioIRQ(Port,MultiIRQ) );
}
}
if(Selection==BB)
{/*** Custom Configuration: BOCA BB2016 ***/
MultiUART = 0x100; MultiIRQ = IRQ10; MultiStatus = MultiUART + 7;
printf("[ Configuring BOCA Board as COM1-COM%d (IRQ%d) @ 0x%x ]\n",
1+ComLimit,MultiIRQ,MultiUART);
ErrorCheck( SioPorts(1+ComLimit,COM1,MultiStatus,BOCABOARD) );
for(Port=COM1;Port<=ComLimit;Port++)
{/* set BOCA Board UART addresses */
ErrorCheck( SioUART(Port,MultiUART+8*Port) );
/* set BOCA Board IRQ */
ErrorCheck( SioIRQ(Port,MultiIRQ) );
}
}
if(Selection==PC)
{/*** Standard Configuration: 4 port card ***/
puts("[ Configuring for PC ]");
for(i=COM1;i<=COM4;i++)
{SioUART(i,StdAdrPC[i]);
SioIRQ(i,StdIrqPC[i]);
}
}
ErrorCheck( SioRxBuf(FirstCOM,0,Size1024) );
ErrorCheck( SioTxBuf(FirstCOM,0,Size1024) );
if(FirstCOM!=SecondCOM)
{ErrorCheck( SioRxBuf(SecondCOM,0,Size1024) );
ErrorCheck( SioTxBuf(SecondCOM,0,Size1024) );
}
/* set port parmameters */
ErrorCheck( SioParms(FirstCOM,NoParity,OneStopBit,WordLength8) );
if(FirstCOM!=SecondCOM) ErrorCheck( SioParms(SecondCOM,NoParity,OneStopBit,WordLength8) );
/* reset the ports */
printf("Resetting COM%d\n",1+FirstCOM);
ErrorCheck( SioReset(FirstCOM,BaudCode) );
if(FirstCOM!=SecondCOM)
{printf("Resetting COM%d\n",1+SecondCOM);
ErrorCheck( SioReset(SecondCOM,BaudCode) );
}
printf("***\n");
printf("*** SELF32 1.0\n");
printf("***\n");
Version = SioInfo('V');
printf("*** Lib Ver : %d.%d\n",Version/16,Version%16);
/* display port info */
Display(FirstCOM);
if(FirstCOM!=SecondCOM) Display(SecondCOM);
printf("***\n");
printf("Starting @ %s baud. COM%d to COM%d\n",argv[4],FirstCOM+1,SecondCOM+1);
/* build TestSet[] array */
for(i=0;i<26;i++) TestSet[i] = 'A'+i;
for(i=0;i<26;i++) TestSet[26+i] = 'a'+i;
for(i=0;i<10;i++) TestSet[52+i] = '0'+i;
TestSet[62] = '\n';
/* clear all buffers */
SioDTR(FirstCOM,'S');
SioRxClear(FirstCOM);
SioTxClear(FirstCOM);
if(FirstCOM!=SecondCOM)
{SioDTR(SecondCOM,'S');
SioRxClear(SecondCOM);
SioTxClear(SecondCOM);
}
printf("Test Set: %s",TestSet);
/* send test sets */
printf("\n Sending set: ");
for(i=0;i<NbrRuns;i++)
{/* send test set again */
printf("%d ",i);
#if 1
for(n=0;n<TEST_SIZE;n++)
{c = TestSet[n];
rc = SioPutc(FirstCOM,c);
if(rc<0)
{printf("Error %d transmitting '%c' (n=%d)\n",rc,c,n);
SioError(rc);
AllDone(1);
}
}
#else
SioPuts(FirstCOM,&TestSet[0],TEST_SIZE);
#endif
}
printf("\n [TxQue = %d bytes; RxQue = %d bytes]",SioTxQue(FirstCOM),SioRxQue(SecondCOM));
/* receive test sets */
printf("\nReceiving set: ");
for(i=0;i<NbrRuns;i++)
{/* receive set again */
printf("%d ",i);
/* receive next test set */
for(n=0;n<TEST_SIZE;n++)
{/* fetch next byte */
rc = SioGetc(SecondCOM,ONE_SECOND);
if(rc<0)
{/* get queue size snapshot immediately */
TxQue = SioTxQue(FirstCOM);
RxQue = SioRxQue(SecondCOM);
/* display error message */
printf("\nERROR: %d bytes received, LastRxChar=%c [%xH]: ",
i*TEST_SIZE+n,LastRxChar,LastRxChar);
SioError(rc);
CheckOverrun(FirstCOM);
if(FirstCOM!=SecondCOM) CheckOverrun(SecondCOM);
printf("Regs: "); for(i=0;i<7;i++) printf("%x ",SioRead(SecondCOM,i) );
printf("\n");
printf("%d bytes left in COM%d TX queue\n", TxQue,1+FirstCOM );
printf("%d bytes left in COM%d RX queue\n", RxQue,1+SecondCOM );
printf("%d system callbacks\n", SioInfo('s') ); /* ????? */
ShowStats(FirstCOM);
if(FirstCOM!=SecondCOM) ShowStats(SecondCOM);
AllDone(2);
}
/* compare character */
LastRxChar = (char)rc;
if(LastRxChar!=TestSet[n])
{/* characters don't match ! */
printf("\nERROR: Received '%c'(0x%x), expected '%c'(0x%x) at n=%d\n",
LastRxChar,LastRxChar,TestSet[n],TestSet[n],n);
printf("%d bytes in COM%d TX queue\n", SioTxQue(FirstCOM),1+FirstCOM );
printf("%d bytes in COM%d RX queue\n", SioRxQue(SecondCOM),1+SecondCOM );
ShowStats(FirstCOM);
ShowStats(SecondCOM);
CheckOverrun(FirstCOM);
if(FirstCOM!=SecondCOM) CheckOverrun(SecondCOM);
AllDone(3);
}
}
} /* end for */
printf("\n\n");
/* check RX FIFO */
TestLength = NbrRuns * TEST_SIZE;
i = SioStats(SecondCOM,'R');
printf("%3d RX interrupts on %d incoming bytes: ", i,TestLength);
if(i<TestLength) puts("RX FIFO is operational");
else puts("RX FIFO is NOT operational [or not 16550 UART]");
if(SioInfo('I'))
{/* check TX FIFO */
i = SioStats(FirstCOM,'T');
printf("%3d TX interrupts on %d outgoing bytes: ", i,TestLength);
if(i<TestLength) puts("TX FIFO is operational");
else puts("TX FIFO is NOT operational [or not 16550 UART]");
}
ShowStats(FirstCOM);
CheckOverrun(FirstCOM);
if(FirstCOM!=SecondCOM)
{ShowStats(SecondCOM);
CheckOverrun(SecondCOM);
}
printf("\n*** SUCCESS: Test AOK !\n\n");
AllDone(0);
} /* end main */
int ErrorCheck(int Code)
{int DpmiCode;
/* trap PCL error codes */
if(Code<0)
{printf("ERROR: ");
SioError(Code);
AllDone(0-Code);
}
return(0);
} /* end ErrorCheck */
void Display(int Port)
{printf("*** COM%d : ",1+Port);
if(Selection==PC) printf("Adr=%3x IRQ=%d",StdAdrPC[Port],StdIrqPC[Port]);
else printf("Adr=%3xh IRQ=%d Status=%xh",MultiUART+8*(Port-COM1),MultiIRQ,MultiStatus);
/* enable FIFO (if 16550) */
if( SioFIFO(Port,LEVEL_8) ) printf(" [16550]\n");
else printf(" [8250/16450]\n");
}
void AllDone(int Code)
{
printf("Shutting down COM%d\n",1+FirstCOM);
SioDone(FirstCOM);
if(FirstCOM!=SecondCOM)
{printf("Shutting down COM%d\n",1+SecondCOM);
SioDone(SecondCOM);
}
exit(Code);
}
void CheckAlloc(int Seg,char *Msg)
{if(Seg==0)
{printf("Cannot allocate memory for %s\n",Msg);
AllDone(5);
}
}
int BaudMatch(char *P)
{int i;
/* find baud rate in table */
for(i=0;i<10;i++) if(strcmp(BaudRate[i],P)==0) return(i);
return(-1);
}
void CheckOverrun(int Port)
{
if(OverrunError&SioLine(Port)) printf("!!! COM%d overrun error !!!\n", 1+Port);
}
void ShowStats(int Port)
{printf("COM%d: %d TX interrupts, %d RX interrupts\n",
1+Port,SioStats(Port,'T'),SioStats(Port,'R') );
printf("COM%d: %d TX bytes kickstarted, %d bytes trans by ISR\n",
1+Port,SioStats(Port,'K'),SioStats(Port,'C') );
}